#include "base_map.h"


//-----------------------------------------------------------------------------
// Associative array
//-----------------------------------------------------------------------------


Map* map_new(void)//cree une map (struct)
{
    Map *map = mem_allocate(sizeof(Map));
    map->data = array_new(0, sizeof(MapPair));
    return map;
}

void map_delete(Map *map) //free map
{
    if(map == 0) { return; }

    MAP_ITERATE(map, pair)
    {
        mem_free(pair->key);
    }
    array_delete(map->data);
    mem_free(map);
    return;
}

int map_insert(Map *map, const char *key, void *data)//map insert
{
    if(map == 0 || key == 0) { return -1; }

    // Search for key duplicate
    MAP_ITERATE(map, pair)
    {
        if(strcmp(pair->key, key) == 0)
        {
            return -1;
        }
    }

    // Insert key
    int insertIndex = array_size(map->data);
    map->data = array_resize(map->data, insertIndex+1);
    map->data[insertIndex].key  = mem_strdup(key);
    map->data[insertIndex].data = data;
    return 0;
}

int map_remove(Map *map, const char *key)//enleve map
{
    if(map == 0 || key == 0) { return -1; }

    // Search the key
    int removeIndex = 0;
    MAP_ITERATE(map, pair)
    {
        if(strcmp(pair->key, key) == 0)
        {
            break;
        }
        removeIndex++;
    }

    // Check if key found
    if(removeIndex == array_size(map->data))
    {
        return -1;
    }
    mem_free(map->data[removeIndex].key);
    memmove(&map->data[removeIndex], &map->data[removeIndex+1], sizeof(MapPair)*(array_size(map->data)-removeIndex-1));
    map->data = array_resize(map->data, array_size(map->data) - 1);
    return 0;
}

void* map_lookup(Map *map, const char *key)//Lookup a value from the map.valeur key
{
    if(map == 0 || key == 0) { return 0; }

    MAP_ITERATE(map, pair)
    {
        if(strcmp(pair->key, key) == 0)
        {
            return pair->data;
        }
    }
    return 0;
}

int map_size(Map *map)//return le nombre d'element dans la map
{
    if(map == 0) { return 0; }

    return array_size(map->data);
}

MapPair* map_iterator(Map *map, MapPair *i)//permet d'itterer dans la map
{
    if(map == 0) { return 0; }

    if(i == 0)
    {
        if(array_size(map->data) == 0)
        {
            return 0;
        }
        return &map->data[0];
    }
    i++;
    if(i >= &map->data[array_size(map->data)])
    {
        return 0;
    }
    return i;
}
